package router

import (
	"fmt"
	"net/http"
	"reflect"
	"strings"
	ginfox "westarry/gin-fox/gin-fox"
	middleware "westarry/gin-fox/gin-fox/middleware"

	"github.com/gin-gonic/gin"
)








func init() {
	fmt.Println("[ginfox]ginfox启动中...")
	fmt.Println("[ginfox]即将开始自动注册路由...")
	middleware.InitAuthPath()
	go ginfox.Gc.L.I.Println("权限节点读取成功")

}
//路由结构体
type R struct {
	reqPath string
	method  reflect.Value
	params  []reflect.Type
}

var Rs = []R{}

func InitR() *gin.Engine {
	gin.SetMode(gin.DebugMode)
	r := gin.Default()
	r.Delims("{[{", "}]}")
	r.LoadHTMLGlob("./static/pages/backend/**/*")
	r.StaticFS("/static", http.Dir("./static")) 
	bindAction(r)
	return r
}
func matchAction(reqPath string, r R) gin.HandlerFunc {
	return func(c *gin.Context) {
		args := make([]reflect.Value, 1)
		args[0] = reflect.ValueOf(c)
		r.method.Call(args)
	}
}
func bindAction(e *gin.Engine) {
	custom:=ginfox.Gc.C.CustomRouter
	for _, r := range Rs {
		for _, c:=range custom{
			if c.ControllerPath==r.reqPath{
				e.Any(c.UrlPath,middleware.InitAuth,matchAction(r.reqPath, r))
			}
		}
		e.Any(r.reqPath, middleware.InitAuth, matchAction(r.reqPath, r))
	}
}

func RegisterController(controllerFile interface{}){
	controllerName := reflect.TypeOf(controllerFile).String()
	module := strings.Split(strings.Split(strings.Split(controllerName, ".")[0], "*")[1], "Controller")[0]
	controller := strings.Split(controllerName, ".")[1]
	fmt.Printf("[ginfox]正在注册控制器%v/%v\n", module, controller)
	methodCount := reflect.ValueOf(controllerFile).NumMethod()
	s := reflect.ValueOf(controllerFile)
	if methodCount > 0 {
		for i := 0; i < methodCount; i++ {
			method := s.Method(i)
			action := getAction(s.Type().Method(i).Name)//将方法转为小驼峰
			requestPath := "/" + module + "/" + controller + "/" + action
			fmt.Printf("[ginfox]注册方法%v=>%v->%v->%v->%v(%v)\n", action, requestPath, module, controller, action, method)
			params := make([]reflect.Type, 0, s.NumMethod())
			r := R{
				reqPath: requestPath, 
				method: method, 
				params: params,
			}
			Rs = append(Rs, r)
		}
	}
}
func getAction(s string)string{
	f:=strings.ToLower(string([]byte(s)[:1]))
	p:=string([]byte(s)[1:len(s)])
	return f+p
} 
